import { AnimationManager } from "./AnimationManager";

/**
 * 动画预设类
 *
 * 提供预定义的角色动画效果，支持参数配置
 */
export class AnimationPresets {
  private animationManager: AnimationManager;

  constructor(animationManager: AnimationManager) {
    this.animationManager = animationManager;
  }

  /**
   * 挥手动画
   *
   * @param character 角色容器对象
   * @param options 动画参数
   * @returns Promise<void> 动画执行完成
   */
  async wave(
    character: any,
    options: {
      angle?: number; // 挥手角度（弧度），默认0.3
      duration?: number; // 动画时长（毫秒），默认500
      direction?: "left" | "right"; // 挥手方向，默认'right'
    } = {}
  ): Promise<void> {
    const { angle = 0.3, duration = 500, direction = "right" } = options;

    // 查找手部精灵（如果存在）
    const leftHand = character.getChildByName?.('leftHand') || character.children?.find((child: any) => child.name === 'leftHand');
    const rightHand = character.getChildByName?.('rightHand') || character.children?.find((child: any) => child.name === 'rightHand');
    
    // 保存原始状态
    const originalRotation = character.rotation;
    const handToAnimate = direction === 'right' ? rightHand : leftHand;
    
    if (handToAnimate) {
      // 如果有手部精灵，只动画手部
      const originalHandRotation = handToAnimate.rotation;
      
      await this.animationManager.animate('wave', (progress) => {
        const easedProgress = this.animationManager.getEasing().easeInOutQuad(progress);
        const swingProgress = Math.sin(easedProgress * Math.PI * 2); // 来回摆动
        handToAnimate.rotation = originalHandRotation + swingProgress * angle; // 使用传入的角度
      }, duration);
      
      // 恢复手部状态
      handToAnimate.rotation = originalHandRotation;
    } else {
      // 如果没有手部精灵，使用轻微的全身旋转来模拟挥手
      await this.animationManager.animate('wave', (progress) => {
        const easedProgress = this.animationManager.getEasing().easeInOutQuad(progress);
        const swingProgress = Math.sin(easedProgress * Math.PI * 2); // 来回摆动
        character.rotation = originalRotation + swingProgress * 0.1; // 减小旋转幅度
      }, duration);
      
      // 恢复原始状态
      character.rotation = originalRotation;
    }
  }

  /**
   * 跳跃动画
   *
   * @param character 角色容器对象
   * @param options 动画参数
   * @returns Promise<void> 动画执行完成
   */
  async jump(
    character: any,
    options: {
      height?: number; // 跳跃高度，默认50
      duration?: number; // 动画时长（毫秒），默认400
      bounces?: number; // 弹跳次数，默认1
    } = {}
  ): Promise<void> {
    const { height = 50, duration = 400, bounces = 1 } = options;
    const originalY = character.y;

    await this.animationManager.animate(
      "jump",
      (progress) => {
        const easedProgress = this.animationManager
          .getEasing()
          .easeInOutQuad(progress);
        let jumpProgress: number;

        if (bounces === 1) {
          jumpProgress = Math.sin(easedProgress * Math.PI);
        } else {
          // 多次弹跳
          jumpProgress =
            Math.sin(easedProgress * Math.PI * bounces) *
            Math.exp(-easedProgress * 2);
        }

        character.y = originalY - height * jumpProgress;
      },
      duration
    );

    character.y = originalY;
  }

  /**
   * 旋转动画
   *
   * @param character 角色容器对象
   * @param options 动画参数
   * @returns Promise<void> 动画执行完成
   */
  async spin(
    character: any,
    options: {
      rotations?: number; // 旋转圈数，默认1
      duration?: number; // 动画时长（毫秒），默认1000
      direction?: "clockwise" | "counterclockwise"; // 旋转方向，默认'clockwise'
    } = {}
  ): Promise<void> {
    const { rotations = 1, duration = 1000, direction = "clockwise" } = options;
    const originalRotation = character.rotation;
    const totalRotation =
      Math.PI * 2 * rotations * (direction === "clockwise" ? 1 : -1);

    await this.animationManager.animate(
      "spin",
      (progress) => {
        character.rotation = originalRotation + totalRotation * progress;
      },
      duration
    );

    character.rotation = originalRotation;
  }

  /**
   * 弹跳动画
   *
   * @param character 角色容器对象
   * @param options 动画参数
   * @returns Promise<void> 动画执行完成
   */
  async bounce(
    character: any,
    options: {
      height?: number; // 弹跳高度，默认30
      duration?: number; // 动画时长（毫秒），默认300
      bounces?: number; // 弹跳次数，默认1
    } = {}
  ): Promise<void> {
    const { height = 30, duration = 300, bounces = 1 } = options;
    const originalY = character.y;

    await this.animationManager.animate(
      "bounce",
      (progress) => {
        let easedProgress: number;

        if (bounces === 1) {
          easedProgress = this.animationManager
            .getEasing()
            .easeOutBounce(progress);
        } else {
          // 多次弹跳使用自定义缓动
          easedProgress =
            Math.sin(progress * Math.PI * bounces) * Math.exp(-progress * 1.5);
        }

        character.y = originalY - height * easedProgress;
      },
      duration
    );

    character.y = originalY;
  }

  /**
   * 摇晃动画
   *
   * @param character 角色容器对象
   * @param options 动画参数
   * @returns Promise<void> 动画执行完成
   */
  async shake(
    character: any,
    options: {
      amount?: number; // 摇晃幅度，默认10
      duration?: number; // 动画时长（毫秒），默认300
      frequency?: number; // 摇晃频率，默认8
      axis?: "x" | "y" | "both"; // 摇晃轴，默认'x'
    } = {}
  ): Promise<void> {
    const { amount = 10, duration = 300, frequency = 8, axis = "x" } = options;
    const originalX = character.x;
    const originalY = character.y;

    await this.animationManager.animate(
      "shake",
      (progress) => {
        const shakeProgress = Math.sin(progress * Math.PI * frequency);
        const dampedAmount = amount * (1 - progress); // 幅度递减

        if (axis === "x" || axis === "both") {
          character.x = originalX + dampedAmount * shakeProgress;
        }
        if (axis === "y" || axis === "both") {
          character.y = originalY + dampedAmount * shakeProgress;
        }
      },
      duration
    );

    character.x = originalX;
    character.y = originalY;
  }

  /**
   * 缩放动画
   *
   * @param character 角色容器对象
   * @param options 动画参数
   * @returns Promise<void> 动画执行完成
   */
  async scale(
    character: any,
    options: {
      scale?: number; // 目标缩放比例，默认1.2
      duration?: number; // 动画时长（毫秒），默认300
      type?: "pulse" | "bounce"; // 缩放类型，默认'pulse'
    } = {}
  ): Promise<void> {
    const { scale = 1.2, duration = 300, type = "pulse" } = options;
    const originalScaleX = character.scale.x;
    const originalScaleY = character.scale.y;

    await this.animationManager.animate(
      "scale",
      (progress) => {
        let easedProgress: number;

        if (type === "pulse") {
          easedProgress = this.animationManager
            .getEasing()
            .easeInOutQuad(progress);
        } else {
          easedProgress = this.animationManager
            .getEasing()
            .easeOutBounce(progress);
        }

        const currentScale = 1 + (scale - 1) * easedProgress;
        character.scale.set(currentScale, currentScale);
      },
      duration
    );

    character.scale.set(originalScaleX, originalScaleY);
  }

  /**
   * 移动动画
   *
   * @param character 角色容器对象
   * @param options 动画参数
   * @returns Promise<void> 动画执行完成
   */
  async move(
    character: any,
    options: {
      x?: number; // X轴移动距离，默认0
      y?: number; // Y轴移动距离，默认0
      duration?: number; // 动画时长（毫秒），默认500
      returnToStart?: boolean; // 是否返回起点，默认false
    } = {}
  ): Promise<void> {
    const { x = 0, y = 0, duration = 500, returnToStart = false } = options;
    const originalX = character.x;
    const originalY = character.y;

    await this.animationManager.animate(
      "move",
      (progress) => {
        const easedProgress = this.animationManager
          .getEasing()
          .easeInOutQuad(progress);
        character.x = originalX + x * easedProgress;
        character.y = originalY + y * easedProgress;
      },
      duration
    );

    if (returnToStart) {
      character.x = originalX;
      character.y = originalY;
    }
  }
}
